#include "numuCCPXAnalysis.hxx"


numuCCPXAnalysis::numuCCPXAnalysis(AnalysisAlgorithm* ana) : baseAnalysis(ana) 
{
  // Minimum accum level to save event into the output tree
  SetMinAccumCutLevelToSave(ND::params().GetParameterI("numuCCPXAnalysis.MinAccumLevelToSave"));

  // Create a numuCCAnalysis passing this analysis to the constructor. In that way the same managers are used
  _numuCCAnalysis = new numuCCAnalysis(this);

  //use it when new version of highland2 is available
  //UseAnalysis(_numuCCAnalysis);

  // Add the package version
  ND::versioning().AddPackage("numuCCPXAnalysis", anaUtils::GetSoftwareVersionFromPath((std::string)getenv("NUMUCCPXANALYSISROOT")));
}


void numuCCPXAnalysis::DefineSelections()
{
  sel().AddSelection("kTrackerNumuCCPX", "inclusive numuCCPX selection",  new numuCCPXSelection(1));
}

bool numuCCPXAnalysis::Process()
{
  //------ This function is called for each bunch and each toy experiment  ----------
  bool passed = sel().GetSelection("kTrackerNumuCCPX")->Apply(*_event,*_ccPX_box); 

  return passed;
}
                                                                                                                                                                                              
void numuCCPXAnalysis::DefineMicroTrees(bool addBase)
{
  // -------- Add variables to the analysis tree ----------------------

  // Variables from the numuCCAnalysis analysis (including the ones in baseAnalysis by default, otherwise addBase should be false
  if (addBase) _numuCCAnalysis->DefineMicroTrees(addBase);

  //--- proton candidate truth variables -------
  AddVarF(output(),selp_truemom, "");              // true proton momentum
  AddVar4VF(output(),selp_truedir, ""); // true proton direction
  AddVarI(output(),selp_pdg,"");

  // --- proton candidate recon variables -----
  AddToyVarI(output(),selp_NDOF,      "");
  AddToyVarF(output(),selp_Chi2,      "");
  AddToyVarF(output(),selp_mom,      "");
  AddVar3VF(output(),selp_dir, "");
  AddVarVI(output(),selp_tpc_nhits,        "", selp_ntpcs);
  AddVar4VF(output(),selp_endpos, "");
}

void numuCCPXAnalysis::FillMicroTrees(bool addBase)
{
  // Fill variables from numuCCAnalysis
  if (addBase) _numuCCAnalysis->FillMicroTrees(addBase);

  if (box().ProtonCandidate) {
    //true variables
    if(  box().ProtonCandidate->TrueTrack ) {
      output().FillVar(selp_truemom,         box().ProtonCandidate->TrueTrack->Momentum);       
      output().FillVectorVarFromArray(selp_truedir,     box().ProtonCandidate->TrueTrack->Direction,   3);       
      output().FillVar(selp_pdg,         box().ProtonCandidate->TrueTrack->PDG);
      
    }
    
    for (Int_t subdet = 0; subdet<3; subdet++) {
      if (!SubDetId::GetDetectorUsed(box().ProtonCandidate->Detector, static_cast<SubDetId::SubDetEnum >(subdet+2))) continue;
      AnaTpcTrack* TPCSegment = static_cast<AnaTpcTrack*>(anaUtils::GetSegmentInDet( *box().ProtonCandidate,static_cast<SubDetId::SubDetEnum >(subdet+2)));
      if (!TPCSegment) continue;
      
      output().FillVectorVar(selp_tpc_nhits,   TPCSegment->NHits);
      //important to have this:
      output().IncrementCounterForVar(selp_tpc_nhits);
      
    }
    
    //basic kinematic variables that wont be changed by systematics propagation
    output().FillVectorVarFromArray(selp_endpos, box().ProtonCandidate->PositionEnd, 4);
    output().FillVectorVarFromArray(selp_dir,    box().ProtonCandidate->DirectionStart, 3);
  } 
}

void numuCCPXAnalysis::FillToyVarsInMicroTrees(bool addBase)
{
  // Variables from the numuCCAnalysis analysis (including the ones in baseAnalysis by default, otherwise addBase should be false
  if (addBase) _numuCCAnalysis->FillToyVarsInMicroTrees(addBase);

  if (box().ProtonCandidate) {
    AnaTrack* ProtonCandidate = static_cast<AnaTrack*>(box().ProtonCandidate);
    //basic kinematic vars
    output().FillToyVar(selp_mom,  ProtonCandidate->Momentum);    
    output().FillToyVar(selp_NDOF,  ProtonCandidate->NDOF);    
    output().FillToyVar(selp_Chi2,  ProtonCandidate->Chi2);    
  }

}

//========================================================================================
//========================================================================================
void numuCCPXAnalysis::InitializeConfiguration()
{
  // Use the same event for the numuCCAnalysis
  _numuCCAnalysis->SetEvent(_event);
  _numuCCAnalysis->InitializeConfiguration();
}

void numuCCPXAnalysis::DefineConfigurations()
{
  // Same configurations as for numuCC
  _numuCCAnalysis->DefineConfigurations();
}

void numuCCPXAnalysis::DefineCorrections()
{
  _numuCCAnalysis->DefineCorrections();
}

void numuCCPXAnalysis::DefineSystematics()
{
  _numuCCAnalysis->DefineSystematics();
}

void numuCCPXAnalysis::DefineTruthTree()
{
  // Variables from baseAnalysis (run, event, ...)
  _numuCCAnalysis->DefineTruthTree();
}

void numuCCPXAnalysis::FillTruthTree(const AnaTrueVertex& vtx)
{
  // Fill the numuCC variables
  //enabling it makes the file output size smaller!!
  _numuCCAnalysis->FillTruthTree(vtx);
}

bool numuCCPXAnalysis::CheckFillTruthTree(const AnaTrueVertex& vtx)
{
  return _numuCCAnalysis->CheckFillTruthTree(vtx);
}

bool numuCCPXAnalysis::CheckFillRooTracker(const AnaTrueVertex& vtx)
{
  return _numuCCAnalysis->CheckFillRooTracker(vtx);
}
                                     
void numuCCPXAnalysis::InitializeToy()
{
  // Delete the box and create a new one
  if (_ccPX_box) delete _ccPX_box;
  _ccPX_box = new AnaBoxCCPX();

  // Use the same box for the numuCCAnalysis
  _numuCCAnalysis->SetBox(_ccPX_box);

  // Use the same event for the numuCCAnalysis
  _numuCCAnalysis->SetEvent(_event);
}
                                                                                                                           
void numuCCPXAnalysis::FinalizeToy()
{
  _numuCCAnalysis->FinalizeToy();
}
